﻿using System;
using System.Diagnostics;
using Fine.Collections.Intf;
using JetBrains.Annotations;



namespace Fine.Collections.Views
{

    /// <summary>
    /// Adapts RList of <b>S</b> to RList of <b>T</b>.
    /// </summary>
    /// <typeparam name="L">type of source list.</typeparam>
    /// <typeparam name="S">type of item of the source collection.</typeparam>
    /// <typeparam name="T">type of item ot the result collection.</typeparam>
    [DebuggerDisplay("Count = {Count}")]
    [DebuggerTypeProxy(typeof(RRandomListAdaptor<,,>.RandomListDebugView))]
    public class RRandomListAdaptor<L,S,T> : RListAdaptor<L,S,T>,
                                             RRandomList<T>
        where L: RRandomList<S>
    {
        public RRandomListAdaptor([NotNull] L source, [NotNull] Converter<S, T> converter)
            : base(source, converter) 
        {}


        public int FirstIndex
        {
            get { return source.FirstIndex; }
        }

        public int LastIndex
        {
            get { return source.LastIndex; }
        }


        public T this[int index]
        {
            get { return converter(source[index]); }
        }


        public int IndexOf(Predicate<T> predicate)
        {
            return source.IndexOf(x => predicate(converter(x)));
        }


        public int IndexOf(Predicate<T> predicate, int startFromIndex)
        {
            return source.IndexOf(x => predicate(converter(x)), startFromIndex);
        }



        #region DEBUG HELPER

        /// <summary>
        /// Debug helper.
        /// </summary>
        internal class RandomListDebugView
        {
            [NotNull]
            private readonly RRandomList<T> list;


            public RandomListDebugView([NotNull] RRandomList<T> list)
            {
                this.list = list;
            }


            [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
            public Array Items
            {
                get
                {
                    int index = list.FirstIndex;
                    var debugArray = DebugViewUtils.MakeArray<T>(index, list.Count);
                    list.ProcessAll(x => debugArray.SetValue(x, index++));
                    return debugArray;
                }
            }
        }

        #endregion

    }

}
